<template>
	<el-dialog title="图片裁剪" :visible.sync="visible" :show-close="false" width="1064px" append-to-body custom-class="image_cropper_dialog">
		<div class="image_cropper_left">
			<vue-cropper ref="cropper" :img="imgBlobUrl" v-bind="cropperConfig" @realTime="handleRealTime"></vue-cropper>
			<el-button-group>
				<el-button type="text" icon="el-icon-refresh" @click="handleCropperRefresh()">重置</el-button>
				<el-button type="text" icon="el-icon-minus" @click="handleChangeScale(true)">缩小</el-button>
				<el-button type="text" icon="el-icon-plus" @click="handleChangeScale(false)">放大</el-button>
				<el-button type="text" icon="el-icon-refresh-left" @click="handleLeftTurn()">左旋转</el-button>
				<el-button type="text" icon="el-icon-refresh-right" @click="handleRightTurn()">右旋转</el-button>
			</el-button-group>
		</div>
		<div class="image_cropper_right">
			<div class="preview" :style="previewImg.div">
				<img :src="previewImg.url" :style="previewImg.img" />
			</div>
			<div class="preinfo">
				<span>宽度：{{ previewImg.cropWidth }}</span>
				<span>高度：{{ previewImg.cropHeight }}</span>
			</div>
		</div>
		<template slot="footer">
			<el-form class="image_cropper_setting" size="small" label-width="70px">
				<el-form-item label="剪切类型">
					<el-radio-group v-model="cropperType" v-removeAriaHidden:radio>
						<el-radio label="[1, 1]">头像</el-radio>
						<el-radio label="[16, 9]">视频</el-radio>
						<el-radio label="[3, 4]">书本</el-radio>
						<el-radio label="[4, 3]">封面</el-radio>
						<el-radio label="custom">自定义</el-radio>
					</el-radio-group>
				</el-form-item>
			</el-form>
			<el-button size="medium" type="primary" @click="handleConfirmCropper()">确定</el-button>
			<el-button size="medium" @click="handleCancelCropper()">取消</el-button>
		</template>
	</el-dialog>
</template>

<script>
import { VueCropper } from 'vue-cropper';
export default {
	name: 'swImageCropper',
	components: { VueCropper },
	props: {
		value: { type: Boolean, default: false },
		type: { type: String, default: '[1, 1]' },
		file: { type: File, default: null }
	},
	data() {
		return {
			visible: this.value,
			cropperConfig: {
				high: true,
				full: true,
				ref: 'cropper',
				mode: 'contain',
				autoCrop: true,
				original: true,
				centerBox: true,
				autoCropWidth: 200,
				autoCropHeight: 200,
				fixedNumber: [1, 1],
				limitMinSize: [200, 100]
			},
			previewImg: {},
			preImage: '',
			imgBlobUrl: '',
			cropperType: this.type
		};
	},
	watch: {
		value(flag) {
			this.visible = flag;
		},
		async visible(flag) {
			this.$emit('input', flag);
			if (!flag) return false;
			this.imgBlobUrl = await this.$fileToBlob(this.file);
		},
		cropperType: {
			handler(val) {
				let valStr = val.replace(/\s/g, '');
				if (valStr === 'custom') {
					this.$set(this.cropperConfig, 'fixed', false);
					this.$set(this.cropperConfig, 'fixedBox', false);
				} else {
					let valArr = !this.$isJSON(valStr) ? [1, 1] : JSON.parse(valStr);
					this.$set(this.cropperConfig, 'fixed', true);
					this.$set(this.cropperConfig, 'fixedBox', true);
					this.$set(this.cropperConfig, 'fixedNumber', valArr);
					if (valStr === '[1,1]') {
						this.$set(this.cropperConfig, 'autoCropWidth', 200);
					} else if (valStr === '[16,9]') {
						this.$set(this.cropperConfig, 'autoCropWidth', 360);
					} else if (valStr === '[3,4]') {
						this.$set(this.cropperConfig, 'autoCropWidth', 240);
					} else if (valStr === '[4,3]') {
						this.$set(this.cropperConfig, 'autoCropWidth', 320);
					} else {
						this.$set(this.cropperConfig, 'autoCropWidth', 320);
						this.$set(this.cropperConfig, 'fixedBox', false);
					}
					if (!!this.$refs['cropper']) {
						this.$refs['cropper'].refresh();
					}
				}
			},
			immediate: true
		}
	},
	methods: {
		//裁剪实时预览
		handleRealTime(data) {
			let preData = { ...data };
			let transform = data.img.transform;
			let scaleStr = transform.split('translate3d')[0];
			let scaleRatio = Number(scaleStr.slice(6).slice(0, -1));
			preData['cropWidth'] = Math.round(data.w / scaleRatio);
			preData['cropHeight'] = Math.round(data.h / scaleRatio);
			this.previewImg = preData;
		},

		//放大/缩小图片
		handleChangeScale(flag) {
			let scale = !flag ? 1 : -1;
			this.$refs['cropper'].changeScale(scale);
		},

		//图片左旋转
		handleLeftTurn() {
			this.$refs['cropper'].rotateLeft();
		},

		//图片右旋转
		handleRightTurn() {
			this.$refs['cropper'].rotateRight();
		},

		//重置图片剪切
		handleCropperRefresh() {
			this.$refs['cropper'].refresh();
		},

		//剪切图片确定
		handleConfirmCropper() {
			this.$refs['cropper'].getCropBlob((blob) => {
				let newFile = new File([blob], this.file.name, { type: this.file.type });
				newFile['uid'] = this.file.uid;
				this.$emit('finish', newFile);
			});
		},

		//取消剪切
		handleCancelCropper() {
			this.visible = false;
			this.$emit('finish', null);
		}
	}
};
</script>
<style lang="scss">
.image_cropper_dialog {
	max-width: 992px;
	.el-dialog__body {
		width: 100%;
		height: 564px;
	}
}
</style>
<style lang="scss" scoped>
.image_cropper_left {
	width: 500px;
	.vue-cropper {
		width: 100%;
		height: 500px;
		flex-shrink: 0;
	}
	.el-button-group {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		margin-top: 16px;
	}
	.el-button {
		padding: 0;
	}
}
.image_cropper_right {
	border-left: solid 1px #e4e7ed;
	margin-left: 15px;
	padding-left: 15px;
	flex: 1;
	overflow: hidden;
	.preview {
		position: relative;
		flex-shrink: 0;
		margin: 0 auto;
		overflow: hidden;
		border: solid 1px #e4e7ed;
	}
	.preinfo {
		margin-top: 16px;
		line-height: 16px;
		text-align: center;
		span {
			margin: 0 15px;
		}
	}
}
:deep(.image_cropper_setting) {
	flex: 1;
	overflow: hidden;
	&.el-form-item {
		margin-bottom: 0;
	}
	.el-form-item__content {
		text-align: left;
	}
}
</style>
